import {ConflictException, Injectable, NotFoundException} from "@nestjs/common";
import {BE_COLLECTED, BOOK, HAVE_READ, USER} from "../../common/constants/neo4jNode";
import {Neo4jDao, RelationshipConfig} from "../common/database/neo4j.dao";

@Injectable()
export class KnowledgeGraphService {

    constructor(
        private readonly neo4jDao: Neo4jDao
    ) {
    }

    /**
     * @Description: 查询图书节点(分页)
     * @author zhaojiuyi
     * @date 2023/4/9
     * @param {number} pageNo 页码
     * @param {number} pageSize 页面大小
     * @return {Promise<Array>} 返回一个图书节点数组
     */
    async getBookNodeList(pageNo: number = 0, pageSize: number = 10) {
        return await this.neo4jDao.getNodeListByPage(BOOK, pageNo, pageSize);
    }

    /**
     * @Description: 根据id查询图书节点
     * @author zhaojiuyi
     * @date 2023/4/10
     */
    async getBookNodeById(userId: string, bookId: string) {
        const result = await this.neo4jDao.findNode(BOOK, {
            id: bookId
        });

        if (result.length) {
            const collection = await this.getUserRelationshipByBook(userId, bookId)
            return {
                ...result[0],
                isCollect: !!collection.length
            }
        }
        throw new NotFoundException("id不存在");
    }

    /**
     * @Description: 根据id查询用户 -（看过）-> 图书
     * @author zhaojiuyi
     * @date 2023/4/10
     */
    async getBookRelationshipByUser(userId: string, bookId: string) {
        const result = await this.neo4jDao.getRelationship({
            fromWhere: {userId},
            nodeFrom: USER,
            nodeTo: BOOK,
            toWhere: {id: bookId}
        });
        if (result) return result['r'];
        throw new NotFoundException("关系不存在");
    }

    /**
     * @Description: 根据id查询图书 -(被收藏)-> 用户
     * @author zhaojiuyi
     * @date 2023/4/10
     */
    async getUserRelationshipByBook(userId: string, bookId: string) {
        const result = await this.neo4jDao.getRelationship({
            fromWhere: {id: bookId},
            nodeFrom: BOOK,
            nodeTo: USER,
            toWhere: {userId}
        });
        if (result) return result['r'];
        throw new NotFoundException("关系不存在");
    }

    /**
     * @Description: 创建用户节点
     * @author zhaojiuyi
     * @date 2023/4/10
     * @param {string} username
     * @param {string} userId
     * @return {string}
     */
    async createUserNode(username: string, userId: string): Promise<null> {
        const result = await this.neo4jDao.findNode(USER, {username, userId});
        if (result.length) throw new ConflictException("用户节点已存在");
        await this.neo4jDao.createNode(USER, {username, userId});
        return null;
    }

    /**
     * @Description: 保存图书与用户的关系(用户阅读过图书)
     * @author zhaojiuyi
     * @date 2023/4/10
     */
    async saveRelationshipFromUserToBookRead(userId: string, bookId: string): Promise<null> {
        const time = new Date().getTime(); // 将阅读时间保存到关系中
        const config: RelationshipConfig = {
            fromWhere: {userId},
            nodeFrom: USER,
            nodeTo: BOOK,
            relationship: HAVE_READ,
            shipProperty: {readTime: time},
            toWhere: {id: bookId}
        };
        await this.neo4jDao.saveRelationship(config);
        return null;
    }

    /**
     * @Description: 保存图书与用户的关系(图书被用户收藏)
     * @author zhaojiuyi
     * @date 2023/4/10
     */
    async saveRelationshipFromUserToBookCollection(userId: string, bookId: string): Promise<null> {
        const config: RelationshipConfig = {
            toWhere: {userId},
            nodeTo: USER,
            nodeFrom: BOOK,
            relationship: BE_COLLECTED,
            fromWhere: {id: bookId}
        };
        await this.neo4jDao.saveRelationship(config);
        return null;
    }


    /**
     * @Description: 删除图书与用户的关系(收藏)
     * @author zhaojiuyi
     * @date 2023/4/10
     */
    async deleteRelationshipFromUserToBookCollection(userId: string, bookId: string): Promise<null> {
        const config: RelationshipConfig = {
            toWhere: {userId},
            nodeTo: USER,
            nodeFrom: BOOK,
            relationship: BE_COLLECTED,
            fromWhere: {id: bookId}
        };
        await this.neo4jDao.deleteRelationship(config);
        return null;
    }

    /**
     * @Description: 随机返回指定类型节点的指定属性
     * @author zhaojiuyi
     * @date 2023/5/17
     * @param {string} nodeType 节点类型
     * @param {number} size 数据长度
     */
    async getNodePropertyListRandom(nodeType: string, size: number): Promise<any[]> {
        const CQL = `match (x:${nodeType}) return x order by rand() limit ${size}`
        return await this.neo4jDao.read(CQL,"x")

    }


}
